package server

import (
	"net"
	"strconv"
	"strings"
)

func ParseIP(s string) (net.IP, int) {
	ip := net.ParseIP(s)
	if ip == nil {
		return nil, 0
	}
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '.':
			return ip, 4
		case ':':
			return ip, 6
		}
	}
	return nil, 0
}

func isInnerIpV4(ipStr string) bool {
	inputIpNum := inetAtonV4(ipStr)
	innerIpA := inetAtonV4("10.255.255.255")
	innerIpB := inetAtonV4("172.16.255.255")
	innerIpC := inetAtonV4("192.168.255.255")
	innerIpD := inetAtonV4("100.64.255.255")
	innerIpF := inetAtonV4("127.255.255.255")

	return inputIpNum>>24 == innerIpA>>24 || inputIpNum>>20 == innerIpB>>20 ||
		inputIpNum>>16 == innerIpC>>16 || inputIpNum>>22 == innerIpD>>22 ||
		inputIpNum>>24 == innerIpF>>24
}

func inetAtonV4(ipStr string) int64 {
	bits := strings.Split(ipStr, ".")

	b0, _ := strconv.Atoi(bits[0])
	b1, _ := strconv.Atoi(bits[1])
	b2, _ := strconv.Atoi(bits[2])
	b3, _ := strconv.Atoi(bits[3])

	var sum int64

	sum += int64(b0) << 24
	sum += int64(b1) << 16
	sum += int64(b2) << 8
	sum += int64(b3)

	return sum
}

func isLocal(ipStr string) bool {
	is := false
	_, n := ParseIP(ipStr)
	if n == 6 {
		if ipStr == "::1" {
			is = true
		}
	} else if n == 4 {
		is = isInnerIpV4(ipStr)
	}
	return is
}
